//  either 函子

class Left { 
  static of(val) { 
    return new Left(val)
  }
  constructor(val) { 
    this._val = val
  }

  map(fn) { 
    return this
  }
}

class Right { 
  static of(val) { 
    return new Right(val)
  }
  constructor(val) { 
    this._val = val
  }

  map(fn) { 
    return Right.of(fn(this._val))
  }
}

// let rl = Right.of(2)
//   .map(x => x + 2)
  
// let r2 = Left.of(2)
//   .map(x => x + 2)  

//   console.log(rl); //  Right { _val: 4 }
//   console.log(r2); // Left { _val: 2 }
  
function parseJson(str) { 
  try { 
    return Right.of(JSON.parse(str))
  } catch (e) { 
    return Left.of({error: e.message})
  }
}

let r = parseJson('{"name": tep}')
console.log(r); // Left { _val: { error: 'Unexpected token n in JSON at position 1' } }



let r1 = parseJson('{"name": "tep"}')
    .map(x => x.name.toUpperCase())
console.log(r1); // Right { _val: { name: 'TEP' } }